package umacis.systemactions;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;


import umacis.lwuitcomponent.Property;
import umacis.lwuitcomponent.property.Constants;
import umacis.lwuitcomponent.property.controller.AllPropertyControllers;

import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.list.ListModel;

public class LayoutDesigner  {

	public class Flags {
		public Flags(int quantity) {
			flags = new long[quantity/NUMBEROFBITSINLONG+1];
		}
		private static final int NUMBEROFBITSINLONG = 64;
		long flags[]; ;
		public void setModified(int propertyIndex) {
			flags[propertyIndex/NUMBEROFBITSINLONG] |= (1 << (propertyIndex%NUMBEROFBITSINLONG));
		}
		public void setUnmodified(int propertyIndex) {
			flags[propertyIndex/NUMBEROFBITSINLONG] ^= (1 << (propertyIndex%NUMBEROFBITSINLONG));
		}
		public boolean isModified(int propertyIndex) {
			return (flags[propertyIndex/NUMBEROFBITSINLONG] & 
					(1 << (propertyIndex%NUMBEROFBITSINLONG))  )  != 0;
		}
	}
	private static final String MODIFIEDFLAGS = "a";
	private static final String PROPERTIESOFMYCHILDREN = "b";
	private static final String PROPERTIES = "d";
	private static final String COMPONENT_index = "e";
	//private static final int NUMBEROFPROPERTIES = 123;
//	private Menu helpMenu;
//	private Menu addComponentMenu;
//	private Component currentComponent;
//	//private PropertyAssigner propertyAssigner;
//
//	public LayoutDesigner() {
//		AllPropertyControllers propertyController = new AllPropertyControllers();
//		if (isDesignable()) {
//			helpMenu = new Menu("Help"); 
//			addComponentMenu = new Menu("Add component");	
//		}
//
//	}
//
//	public Actions getActions() {
//		Actions actions = super.getActions();
//		if (isDesignable()) {
//			
//			actions.setGroup("Layout designer");
//			actions.add(helpMenu);
//			helpMenu.add("Outline");
//			helpMenu.add("Status");
//			actions.add(addComponentMenu);
//			actions.add(new Handle("Outline")  {  public void execute(){showOutlineScreen();} });
//			actions.add(new Handle("Status")  {  public void execute(){showStatusDialog();} });
//			actions.add(new Handle("Properties")  {  public void execute(){showPropertiesScreen();} });
//			actions.add(new Handle("Edit property")  {  public void execute(){editProperty();} });
//			actions.add(new Handle("Bindings")  {  public void execute(){showBindings();} });
//			actions.add(new Handle("LayoutChooser")  {  public void execute(){chooseLayout();} });
//			
//			actions.add(new Handle("up")  {  public void execute(){up();} });
//			actions.add(new Handle("down")  {  public void execute(){down();} });
//			actions.add(new Handle("left")  {  public void execute(){left();} });
//			actions.add(new Handle("right")  {  public void execute(){right();} });
//			actions.add(new Handle("select")  {  public void execute(){select();} });
//		}
//		return actions;
//
//	}

	protected void up() {
	}
	protected void down() {
	}
	protected void left() {
	}
	protected void right() {
	}
	protected void select() {
	}
	protected void chooseLayout() {
	}

	protected void showBindings() {
	}

	protected void editProperty() {
	}

	protected void showPropertiesScreen() {
	}

	protected void showStatusDialog() {
	}

//	public Bindings getBindings() {
//		Bindings bindings = super.getBindings();
//				if (isDesignable()) {
//					
//					bindings.set(Key.ONE, Key.NORMAL, helpMenu,Binding.FLAGS_none);
//					bindings.set(Key.LSK, Key.NORMAL, OutlineScreen.class,Binding.FLAGS_none);
//					//bindings.set(Key.RSK, Key.NORMAL, OutlineScreen.class ,Binding.FLAGS_none);
//					bindings.set(Key.STAR, Key.NORMAL, "LayoutChooser" ,Binding.FLAGS_none);
//					bindings.set(Key.HASH, Key.NORMAL, "Properties" ,Binding.FLAGS_none);
//					bindings.set(Key.GREENKEY, Key.NORMAL, "Status" ,Binding.FLAGS_none);
//
//					bindings.set(Key.UP, Key.NORMAL, "up",Binding.FLAGS_none);
//					bindings.set(Key.DOWN, Key.NORMAL, "down",Binding.FLAGS_none);
//					bindings.set(Key.LEFT, Key.NORMAL, "left" ,Binding.FLAGS_none);
//					bindings.set(Key.RIGHT, Key.NORMAL, "right" ,Binding.FLAGS_none);
//					bindings.set(Key.SELECT, Key.NORMAL, "select" ,Binding.FLAGS_none);
//
//
//				}
//		return bindings;
//	}
//
//	public void emptyAction(int key, int state, Action action) {
//		if (action==null) {
//			Umacis.log("oops, action should not be null!!! in handlelessAction in designer"); return;
//		}
//		Umacis.log("Layout.emptyAction: we're here now");
//		Umacis.log("action: name = "+action.name+ " group = " +action.group + " type = ", action.type);
//		if (!isDesignable()) super.emptyAction(key, state, action);
//		Umacis.log("Themeable: "+action.name +"Menu name ="+ action.group);
//		String menuName = action.group;
//		String stringSelected = action.name;
//		int selIndex = action.menuIndex;
//		//		if (menuName.equals(componentMenu.name)) {
//		//			if (selIndex == 3) currentStyle = baseContainer.getSoftButtonStyle(); //I can't get at the menubar component..
//		//			
//		//			else currentStyle = components[selIndex].getStyle();
//		//			setSoftKeyText(LSK_OFFSET, stringSelected);
//		//			currentComponent = components[selIndex];
//		//			if (selIndex!= 0) UIID = stringSelected + ".";
//		//			else UIID = ""; //all components
//		//		}
//		//				//an attribute has been picked
//		//		else if (menuName.equals(attributeMenu.name) && currentStyle!=null) {
//		//			//selectedAttributeName = item.name;
//		//			selectedAttributeIndex = selIndex;
//		//			
//		//			uiidAttribute = UIID + stringSelected;
//		//			switch (selectedAttributeIndex) {
//		//			case  bgColor : 
//		//			case  fgColor : 
//		//			case  bgSelectionColor : 	
//		//			case  fgSelectionColor : 	//int color = currentStyle.getBgColor();
//		//										//red = color & 0x00FF0000; blue = color & 0x000000FF; green = color & 0x0000FF00;
//		//										setSoftKeyText(RSK_OFFSET, stringSelected+" "+NAME_rgb[rgb]); 
//		//										break;
//		//			case  border : break; 
//		//
//		//			case  font :  setSoftKeyText(RSK_OFFSET, stringSelected);  break; 
//		//
//		//			case  margin : 
//		//			case  padding : setSoftKeyText(RSK_OFFSET, stringSelected+ " "+NAME_tblr[tblr]);
//		//							break;
//		//							
//		//			case  bgImage : 
//		//			case  transparency :
//		//			case  scaledImage : 
//		//			default: ;
//		//			
//		//			}
//		//			
//		//		}
//		//		else if (menuName.equals(fontMenu.name)) {
//		//			Umacis.log("Themeable.menuActionPerformed: font selected ="+stringSelected);
//		//			Font font = Umacis.getResource("fonts").getFont(stringSelected);
//		//			setSoftKeyText(RSK_OFFSET, NAME_attributes[selectedAttributeIndex] + " "+stringSelected); 
//		//			currentFont = selIndex;
//		//			currentStyle.setFont(font);
//		//			baseContainer.repaint();
//		//		}
//		//		else super.emptyAction(key, state, action);
//
//	}

	//	public void setup() {
	//		super.setup();
	//		baseContainer = null;
	//		Umacis.log("setup called in layout designer");
	//		
	//	}
	
	public void setup() {
		
	}
	
	
	public void showOutlineScreen() {
		
	}
//	/****************************************************************************

	public void addComponent(Container container, int index)  {
		Component cmp = instantiateComponent( COMPONENTS_path +NAMES_components[index] );
		container.addComponent(cmp);
		applyInheritedProperties(cmp);
		cmp.putClientProperty(COMPONENT_index, new Integer(index));
	}

//	private void setProperty(int property, int parameter) {
//		//		Properties properties = getProperties(currentComponent);
//		//		properties.set(property, parameter);
//		propertyAssigner.set( currentComponent, getProperties(currentComponent), property, parameter);
//	}

	private Hashtable getProperties(Component cmp) {
		Hashtable properties = (Hashtable)cmp.getClientProperty(PROPERTIES);
		if (properties == null) {
			properties = new Hashtable();
			cmp.putClientProperty(PROPERTIES, properties);
		}
		return properties;
	}

	private Component instantiateComponent(String componentName)  {

		Component component = null;
		try {
			component = (Component) Class.forName(componentName).newInstance();

		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			//			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return component;		
	}

	private String getComponentName(Component cmp) {
		String name = cmp.getClass().getName();
		return name.substring(name.lastIndexOf('.')+1);
	}

	private void applyInheritedProperties(Component cmp) {
		applyProperties(cmp, new Flags(Constants.NUMBER_OF_PROPERTIES), cmp.getParent());
	}
	//	
	private void applyProperties(Component cmp, Flags flags, Container parentContainer) {
		if (parentContainer == null) return;
		Hashtable inheritedProperties = (Hashtable)parentContainer.getClientProperty(PROPERTIESOFMYCHILDREN);
		if (inheritedProperties != null) {
			Enumeration e = inheritedProperties.elements();
			while (e.hasMoreElements()) {
				Property property = ((Property)e.nextElement());
				if (!flags.isModified(property.index)) {
					property.applyParameters(cmp);
					flags.setModified(property.index);
				}

			}
		}
		applyProperties(cmp, flags, parentContainer.getParent());
	}

//	private void listComponents(Vector allComponents, Vector allComponentsNames,String indentation, Container container)
//	DefaultListModel listModel = umacis.getOutlineListModel();
//	
//	listModel = umacis.getOutlineListModel();
//		listComponents(allComponents, allComponentsNames, "", baseContainer); 
//	}
	
	private Vector listComponents(Vector allComponents, ListModel outlineMenu,String indentation, Container container) {
		Component[] components = new Component[container.getComponentCount()];
		//Umacis.log("Themeable: component count",container.getComponentCount());
		for (int i=0;i<components.length;i++) {
			Component c = container.getComponentAt(i);
			allComponents.addElement(c);
			outlineMenu.addItem(indentation + c.getUIID());
			
			//Umacis.log("Themeable: "+c.getClass().getName());
			if (Container.class.isInstance(c)) listComponents(allComponents, outlineMenu, indentation + " ",(Container)c);
		}
		return allComponents;
	}
	
//	private void showOutlineMenu(int type) {
//		Vector outline = new Vector();
//		componentMenu.removeAllItems();
//		Vector componentsNames = new Vector();
//		listComponents(outline, componentsNames, "", baseContainer);
//		
//		
//		
////		components = new Component[6 + allComponents.size()];
////		if (type == GLOBAL) {
////			
////			
////			componentMenu.removeAllItems();
////			components[0] = null; 									componentMenu.add("All");
////			components[1] = baseContainer;								componentMenu.add("Form");
////			components[2] = baseContainer.getTitleComponent();			componentMenu.add("Title");
////			components[3] = null;									componentMenu.add("SoftButton");
////			components[4] = baseContainer.getSoftButton(LSK_OFFSET);	componentMenu.add("LSK");
////			components[5] = baseContainer.getSoftButton(RSK_OFFSET);	componentMenu.add("RSK");
////			
//			
//			Enumeration e = componentsNames.elements();
//			int index = 0;
//			while (e.hasMoreElements()) {
//				Component c = (Component) e.nextElement();
//				componentMenu.add((String)e.nextElement()); //Umacis.getClassName(c.getClass()));
////				components[6+index++] = c;
////				Umacis.log("Themeable: "+Umacis.getClassName(c.getClass()));
////				Umacis.log("Themeable:" + (String)c.getClientProperty("id"));
//				
//			}
////		}
////		else 
////		{
////			
////			componentMenu.removeAllItems();
////			components[0] = null; 									componentMenu.add("all");
////			components[1] = baseContainer;								componentMenu.add("base container");
////			components[2] = baseContainer.getTitleComponent();			componentMenu.add("title");
////			components[3] = null;									componentMenu.add("softButton");
////			components[4] = baseContainer.getSoftButton(LSK_OFFSET);	componentMenu.add("lsk");
////			components[5] = baseContainer.getSoftButton(RSK_OFFSET);	componentMenu.add("rsk");
////			
////			//Component[] listedComponents = listComponents();
////			Enumeration e = allComponents.elements();
////			int index = 0;
////			while (e.hasMoreElements()) {
////				Component c = (Component) e.nextElement();
////				componentMenu.add(Umacis.getClassName(c.getClass()));
////				components[6+index++] = c;
////				Umacis.log("Themeable: "+Umacis.getClassName(c.getClass()));
////				Umacis.log("Themeable:" + c.getClientProperty("id"));
////				
////			}
////		}
//		componentMenu.show();
//	}
	//component types
	public static final int MAXNUMBEROF_componentTypes = 14;
	static private final String COMPONENTS_path = "com.sun.lwuit.";
	private static final String[] NAMES_components = { "Container", "Label", "Button", "TabbedPane", "CheckBox", "RadioButton",
		"TextArea", "TextField", "List", "ComboBox", "Tree", "ProgressBar", "Calendar" }; /*etc XXX */  

//	static private final String CLASS_container = "com.sun.lwuit.Container";
//	static private final String CLASS_label = "com.sun.lwuit.Label";
//	static private final String CLASS_button = "com.sun.lwuit.Button";
//	static private final String CLASS_tabbedPane = "com.sun.lwuit.TabbedPane";
//	static private final String CLASS_checkBox = "com.sun.lwuit.CheckBox";
//	static private final String CLASS_radioButton = "com.sun.lwuit.RadioButton";
//	static private final String CLASS_textArea = "com.sun.lwuit.TextArea";
//	static private final String CLASS_textField = "com.sun.lwuit.TextField";
//	static private final String CLASS_list = "com.sun.lwuit.List";
//	static private final String CLASS_comboBox = "com.sun.lwuit.ComboBox";
//	static private final String CLASS_tree = "com.sun.lwuit.Tree"; //??
//	static private final String CLASS_progressBar = "com.sun.lwuit.ProgressBar";  //??
//	static private final String CLASS_calender = "com.sun.lwuit.Calender";
	//static private final String CLASS_media = "com.sun.lwuit.MediaComponent"; //?? doesn't have a zero argument constructor..


}
